package com.adjaisd.scarecrow.service.impl;

import com.adjaisd.scarecrow.dto.HeapPoint;
import com.adjaisd.scarecrow.dto.TrendPoint;
import com.adjaisd.scarecrow.entity.Device;
import com.adjaisd.scarecrow.entity.DeviceStatus;
import com.adjaisd.scarecrow.repo.TimeSeriesRepository;
import com.adjaisd.scarecrow.service.DeviceService;
import com.adjaisd.scarecrow.service.DeviceStatusService;
import com.adjaisd.scarecrow.service.QuotaService;
import com.adjaisd.scarecrow.service.ReportService;
import com.adjaisd.scarecrow.vo.PieVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    DeviceService deviceService;

    @Autowired
    DeviceStatusService deviceStatusService;

    @Override
    public List<PieVO> getDeviceStatusChart(Long userId) {
        LinkedList<PieVO> list = new LinkedList<>();
        // 获取设备列表
        List<Device> deviceList = deviceService.getDeviceListByUID(userId);
        long all = deviceList.size(), status = 0, online = 0, alarm = 0;
        for (Device device : deviceList) {
            DeviceStatus deviceStatus = deviceStatusService.getDeviceStatusByID(device.getId());
            if (deviceStatus.getStatus()) status++; // 开启
            if (deviceStatus.getStatus() && deviceStatus.getOnline()) online++; // 开启且在线
            if (deviceStatus.getStatus() && deviceStatus.getOnline() && // 开启且在线且报警
                    deviceStatus.getAlarm()) alarm++;
        }
        PieVO vo1 = new PieVO("all", all);
        list.add(vo1);
        PieVO vo2 = new PieVO("status", status);
        list.add(vo2);
        PieVO vo3 = new PieVO("online", online);
        list.add(vo3);
        PieVO vo4 = new PieVO("alarm", alarm);
        list.add(vo4);
        return list;
    }

    @Autowired
    QuotaService quotaService;

    @Autowired
    TimeSeriesRepository timeSeriesRepository;

    @Override
    public List<TrendPoint> getAlarmTrend(Long userId, String beg, String end, int type) {
        // 拼接设备ID正则
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Device::getOwnerId, userId)
                .gt(Device::getBindTime, 0L);
        List<Device> deviceList = deviceService.list(wrapper);

        List<String> list = new LinkedList<>();
        deviceList.forEach(device -> list.add(device.getId() + ""));
        String join = String.join("|", list);

        StringBuilder ql = new StringBuilder("select count(value) as pointValue from quota where alarm='1' ");
        ql.append("and deviceId=~/^").append(join).append("$/ ");
        ql.append("and time>='" + beg + "' and time<='" + end + "' ");

        if (type == 1) ql.append("group by time(1m)");
        else if (type == 2) ql.append("group by time(1h)");
        else if (type == 3) ql.append("group by time(1d)");
        else return null;

        return timeSeriesRepository.query(ql.toString(), TrendPoint.class);
    }

    @Override
    public List<HeapPoint> getTop10Alarm(Long userId, String beg, String end) {
        // 拼接设备ID正则
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Device::getOwnerId, userId)
                .gt(Device::getBindTime, 0L);
        List<Device> deviceList = deviceService.list(wrapper);

        List<String> list = new LinkedList<>();
        deviceList.forEach(device -> list.add(device.getId() + ""));
        String join = String.join("|", list);

        StringBuilder ql = new StringBuilder("select top(heapValue,deviceId,quotaId,\"name\",10 )  as heapValue ");
        ql.append("from (select count(value) as heapValue from quota where alarm='1' ");
        ql.append("and deviceId=~/^").append(join).append("$/ ");
        ql.append("and time>='" + beg + "' and time<='" + end + "' ");
        ql.append("group by deviceId,quotaId,\"name\"  ) order by desc");

        return timeSeriesRepository.query(ql.toString(), HeapPoint.class);
    }
}
